package com.xwj.xuthread.spring.task;

import cn.hutool.json.JSONUtil;
import com.xwj.xuthread.spring.core.ThreadPoolManager;
import com.xwj.xuthread.spring.core.XuDynamicThreadPool;
import com.xwj.xuthread.spring.nacos.ThreadPoolNacosConfig;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.*;

/**
 * @Author: XuWenjie
 * @Date: 2025-08-25
 * @Description: ThreadPoolMonitor
 */
@Slf4j
public class ThreadPoolMonitor {

    @Autowired
    private ThreadPoolNacosConfig nacosConfig;

    private ScheduledExecutorService scheduler;

    private final Map<String,Long> rejectCountMap = new ConcurrentHashMap<>();

    @PostConstruct
    public void init(){
        scheduler = Executors.newScheduledThreadPool(
                1, Executors.defaultThreadFactory()
        );
        // 每指定时间检查一次，初始延迟0秒
        scheduler.scheduleWithFixedDelay(() -> {
            ThreadPoolManager.getAllThreadPools().forEach(pool ->{
                checkActive(pool);
                checkQueue(pool);
                checkReject(pool);
            });
        }, 0, nacosConfig.getMonitor().getInterval(), TimeUnit.SECONDS);
    }

    private void checkReject(XuDynamicThreadPool pool) {
        long latestRejectCount = rejectCountMap.getOrDefault(pool.getThreadPoolId(), 0L);
        long currentRejectCount = pool.getRejectCount().get();
        // 如果当前拒绝任务数量大于最新记录的拒绝任务数量，说明拒绝任务数量增加
        if (currentRejectCount > latestRejectCount) {
            log.warn("线程池拒绝任务，线程池名称：{}，线程池状态：{}", pool.getThreadPoolId(), JSONUtil.parse(pool));
            rejectCountMap.put(pool.getThreadPoolId(), currentRejectCount);
        }
        if(currentRejectCount > nacosConfig.getMonitor().getRejectCount()){
            log.warn("线程池拒绝任务数量超过阈值，线程池名称：{}，线程池状态：{}", pool.getThreadPoolId(), JSONUtil.parse(pool));
        }
    }
    private void checkActive(XuDynamicThreadPool pool) {
        if (pool.getActiveCount() * 100 > pool.getMaximumPoolSize() * nacosConfig.getMonitor().getActiveRate()){
            log.warn("线程活跃度超过阈值，线程池名称：{}，线程池状态：{}", pool.getThreadPoolId(), JSONUtil.parse(pool));
        }
        else{
            log.info("线程池活跃度正常，线程池名称：{}，线程池状态：{}", pool.getThreadPoolId(), JSONUtil.parse(pool));
        }
    }
    private void checkQueue(XuDynamicThreadPool pool) {
        if (pool.getQueue().size() * 100 > (pool.getQueue().size()+pool.getQueue().remainingCapacity()) * nacosConfig.getMonitor().getCapacityRate()){
            log.warn("队列长度超过阈值，线程池名称：{}，线程池状态：{}", pool.getThreadPoolId(), JSONUtil.parse(pool));
        }
    }
    // 固定速率执行（每10秒执行一次）
    @Scheduled(fixedDelay = 10000)
    public void executeEvery10Seconds() {
        log.info("定时任务监控线程池 - " + System.currentTimeMillis());
        // 在这里添加你的业务逻辑
        ThreadPoolManager.getAllThreadPools().forEach(pool ->{
            log.info("线程池名称：{}，线程池状态：{}", pool.getThreadPoolId(), JSONUtil.parse(pool));
        });
    }



    // 或者使用 cron 表达式
//    @Scheduled(cron = "*/10 * * * * ?")
//    public void executeEvery10SecondsWithCron() {
//        System.out.println("Cron定时任务执行 - " + System.currentTimeMillis());
//    }
}
